/*
 * AbstractProfiler.h
 *
 *  Created on: 2011-04-10
 *      Author: Jagger
 */

#ifndef ABSTRACTPROFILER_H_
#define ABSTRACTPROFILER_H_

#include <omnetpp.h>
#include <list>
#include "NetPacket_m.h"

/**
 * Klasa abstrakcyjna definiujaca funkcjonalnosc typowego profilera ruchu
 * sieciowego. Stosowny algorytm profilowania jest zaimplementowany w metodzie
 * 'acceptPacket'.
 */
class AbstractProfiler : public cSimpleModule
{
	// PARAMETRY DO STATYSTYK
	cMessage* bandwidthEvent;
	simsignal_t inputSignal;
	simsignal_t outputSignal;

	uint32_t inputBandwidthSum;
	uint32_t outputBandwidthSum;

	void calcMeanBandwidth();
	// KONIEC PARAMETROW DO STATYSTYK

protected:
	simtime_t endTime;

	/**
	 * Maksymalna dlugosc kolejki. Po osiagnieciu tej dlugosci kazde kolejne
	 * pakiety beda odrzucane. Wartosc 0 symbolizuje nieskonczona dlugosc.
	 */
	uint32_t maxQueueSize;
	/**
	 * Kolejka pakietow oczekujacych na wyslanie.
	 */
	std::list<NetPacket*> queue;

	// PARAMETRY DO STATYSTYK
	/**
	 * Czas co ktory wyliczamy na nowo zuzycie przepustowosci.
	 */
	simtime_t bandwidthCalcTick;
	/**
	 * Wykorzystanie przepustowosci na wejsciu profilera na przedziale czasu
	 * [t, t + meanCalcTick].
	 */
	double inputBandwidth;
	/**
	 * Wykorzystanie przepustowosci na wyjsciu profilera na przedziale czasu
	 * [t, t + meanCalcTick].
	 */
	double outputBandwidth;
	// KONIEC PARAMETROW DO STATYSTYK

	/**
	 * Iniciuje parametr 'maxQueueSize'.
	 */
	virtual void initialize();
	/**
	 * Zajmuje sie obsluga wewnetrznych i zewnetrznych pakietow.
	 */
	virtual void handleMessage(cMessage* msg);

	/**
	 * Informuje czy ten profiler jest jeszcze w stanie przyjmowac pakiety.
	 */
	bool canReceive();

	/**
	 * Decyduje czy przeslac dany pakiet. Gdy metoda ta zwraca 'true', pakiet
	 * jest przesylany dalej, w przeciwnym wypadku czeka on okreslony czas w
	 * kolejce. Parametr 'delay' metody 'acceptPacket' jest potrzebny tylko
	 * wtedy gdy metoda ta zwraca 'false'. Mowi on o czasie jaki nalezy
	 * odczekac, aby ponownie sprawdzic czy dany pakiet mozna wyslac.
	 */
	virtual bool acceptPacket(NetPacket* packet, simtime_t& delay) = 0;
};

#endif /* ABSTRACTPROFILER_H_ */
